﻿//===========================[ 7 / 6 / 2011 LVI ]=============================
//				Copyright c Vitaly Lyaschenko <SkyChameleon@gmail.com>
// 								Header file
// Purpose: устройства рендера(Render Device) надстройка над OpenGL 3.3 API
//=============================================================================
#pragma once

#include "common.h"
#include "cTexture.h"
#include "cVertexArray.h"
#include "cVertexBuffer.h"
#include "cProgramManager.h"
#include "cMaterial.h"
#include "cLight.h"

#include "windows.h"

struct DisplayCfg 
{
	uint width;
	uint height;
	uint frequency;
	bool fullScreen;
	bool showCursor;
	bool antialiasing;

	float Xcenter,Ycenter;

	DisplayCfg() : 
	      width(0),
	      height(0),
		  frequency(0),
		  fullScreen(false),
		  showCursor(false),
		  antialiasing(false)
	{	}
};

enum drawMode
{
	Points		 = 1,
	Lines		 = 2,
	LineStrip	 = 3,
	Triangles	 = 4,
	TriangleStrip= 5,
};

enum fillMode
{
	Fill_Point	  = 1,
	Fill_Wireframe= 2,
	Fill_Solid	  = 3,
};

struct primitive
{   
	uint mode,
	     offset,
	     size;
};

class cRenderDevice
{
public:
	cRenderDevice(void);
	~cRenderDevice(void);

	bool init( HWND hWindow, DisplayCfg *setting );
	bool release();

	void clear(/* vec4 color, float depth, uint stencil*/ );
	void setViewport( int x, int y, int width, int height );
	void setDrawPrimitiveMode( const drawMode mode );
	void setFillMode( fillMode mode);

	void createProgram( const char* VertFile, const char* fragFile, const char* nameProg );
	cShaderProgram *getProgram( const char* nameProg );
	// создает VAO (vertex array object)
	cVAO *createVArray();
	// создание VBO (vertex buffer object) для атрибутов вершин
	cVBO *createVBuffer( size_t size, const void *pData, usageBuffer usage = gl_STATIC_DRAW );
	// создание VBO для данных индексов
	cVBO *createVBufferEl( size_t size, const void *pData, usageBuffer usage = gl_STATIC_DRAW );
	// установка вершинных атрибутов
	void setAttrPtr( uint program, const char * name, int numComponents, int stride, void * ptr, bool normalized = false );
	void setAttrPtr( int vertLoc, int numComponents, int stride, void * ptr, bool normalized = false );
	
	void setLight( cShaderProgram *pProgram, cLight &light );
	void setMaterial( cShaderProgram *pProgram, const cMaterial *pMaterial, int texId = 0 ); // txId индекс текстурного юнита

	cTexture * createTexture( int minFilter, int magFilter, int warp, uint target, cImage *image, bool MIPs = false );
	void setTexture( cTexture *pTexture, cShaderProgram *program, uint texUnit );

	void drawArrays( uint startVertex, int primitiveCount );
	// dip с индексами размером в 16 byte (ushort)
	void drawElements16( int primitiveCount );
	// dip с индексами размером в 32 byte (uint)
	void drawElements32( int primitiveCount );

	void swapBuffers();

private:
	HWND hWnd;
	HDC	 hDC;
	HGLRC m_hGLRC;

	primitive m_prim;
	DisplayCfg *pSetting;
};

